package hehe.router;

import hehe.router.util.RouteHelper;
import java.lang.reflect.Constructor;
import java.util.*;

/**
 * url 地址类
 *<B>说明：</B>
 *<pre>
 *　负责解析路由规则,生成对应的URL地址
 *  一个url 对应一套路由规则, Url,Router 对象一对一
 *</pre>
 *<B>示例：</B>
 *<pre>
 *
 *  示例:脱离容器,创建URL对象
 *  ```java
 *    Map<String,Object> attrs = new HashMap<String,Object>(){{
 *    put("ref","hehe.router.easy.Easy");
 *    put("actionSuffix","Action");
 *    put("defaultPackage","app.controller");
 *    put("controllerSuffix","Controller");
 *    }};
 *
 *    Url url = new Url(attrs);
 *
 *  ```
 *
 *  示例:普通规则
 *  ```java
 *  Map<String,Object> attrs = new HashMap<>();
 *  // 指定对应的路由类
 *  attrs.put("ref","hehe.router.easy.Easy");
 *  Url url = new Url();
 *　// 新增路由规则
 *  Map<String,String> rule = new HashMap<String,String>();
 *  rule.put("pathinfoRule","<controller:\\\\w+>/<action:\\\\w+>");
 *  rule.put("urlRule","<controller>/<action>");
 *
 *  url.addRule(rule);
 *  // 解析URL地址,查找对应的控制器
 *
 *  Controller urlController = url.findController("user/add","GET");
 *
 *  // 获取对应的控制器类名,方法名
 *  String controllerName = urlController.getController();
 *  String actionName = urlController.getAction();
 *  // controllerName对应值app.controller.IndexController
 *  // actionName 对应值addAction
 *  生成URL地址
 *  String uri = url.createUrl("user/add");
 *
 *  ```
 *</pre>
 *<B>日志：</B>
 *<pre>
 *  略
 *</pre>
 *<B>注意事项：</B>
 *<pre>
 *  略
 *</pre>
 */
public class Url
{
    /**
     * 当前路由对象
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected Router router;

    /**
     * 当前路由对象包名
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    protected String ref;

    /**
     * action 名称前缀
     *<B>说明：</B>
     *<pre>
     * 属性详细描述
     *</pre>
     */
    protected String actionPrefix = "";

    /**
     * action 名称后缀
     *<B>说明：</B>
     *<pre>
     * 属性详细描述
     *</pre>
     */
    protected String actionSuffix = "";

    /**
     * 控制器默认包
     *<B>说明：</B>
     *<pre>
     * 比如:app.controller
     *</pre>
     */
    protected String defaultPackage = "";

    /**
     * 控制器名称后缀
     *<B>说明：</B>
     *<pre>
     * 比如:app.controller
     *</pre>
     */
    protected String controllerSuffix = "";





    private Map<String,Object> attrs = new HashMap<>();

    public Url()
    {

    }

    public Url(Map<String,Object> attrs)
    {
        RouteHelper.setAttrs(this,attrs);
    }

    public Router getRouter()
    {
        if (this.router == null) {
            try {
                Class<?> router = Class.forName(this.ref);
                if (this.attrs.size() == 0) {
                    this.router = (Router)router.newInstance();
                    return this.router;
                }

                // 有参数据
                Constructor constructor = router.getDeclaredConstructor(Map.class);
                this.router = (Router)constructor.newInstance(this.attrs);

                return this.router;
            } catch (ClassNotFoundException ex) {
                return null;
            } catch (Exception ex) {
                return null;
            }
        }

        return this.router;
    }

    public void addRule(Map<String,String> rule)
    {
        this.getRouter().addRule(rule);
    }

    /**
     * 格式化控制器名称
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     */
    protected String formatControllerName(String controllerName)
    {
        return this.defaultPackage + "." +  RouteHelper.upperCase(controllerName) + this.controllerSuffix;
    }

    /**
     * 格式化action名称
     *<B>说明：</B>
     *<pre>
     * 略
     *</pre>
     */
    protected String formatActionName(String actionName)
    {
        return this.actionPrefix + actionName + this.actionSuffix;
    }

    /**
     * 查找控制器
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     * @param pathInfo HttpServletRequest 请求
     * @return  Controller 控制器
     */
    public Controller findController(String pathInfo,String method)
    {
        Controller controller = this.getRouter().findController(pathInfo,method);

        if (controller != null) {
            controller.setController(this.formatControllerName(controller.getController()));
            controller.setAction(this.formatActionName(controller.getAction()));
        }

        return controller;
    }

    public String createUrl(String url)
    {
        Map<String,String> params = new HashMap<>();
        return this.createUrl(url,params,null);
    }

    public String createUrl(String url,Map<String,String> params)
    {
        return this.createUrl(url,params, null);
    }

    /**
     * 创建url 地址
     *<B>说明：</B>
     *<pre>
     *  略
     *</pre>
     */
    public String createUrl(String url,Map<String,String> params,String method)
    {
        RequestUrl requestUrl = this.getRouter().createUrl(url,params,method);
        if (requestUrl == null) {
            return "";
        }

        return requestUrl.getUrl();
    }

}
